package com.lizi.core.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Random;


/**
 * 数字处理工具类
 *
 * 注：商品购买成功后，返还积分时按照 1元 = 1积分 的规则返还
 *    购买商品消耗积分时，按照 1积分 = 1分 的规则计算
 *
 */
public class NumberUtil {

    //默认保留的小数位数
    public static int DEFAULT_DIV_SCALE = 2;
    public static int INTEGER_SCALE = 0;
    public static String YUAN_FORMAT_PATTEN = "#0.00";
    public static String COUPON_FORMAT_PATTEN = "#0";
    public static DecimalFormat minFormat = new DecimalFormat("#0.00");
    public static Random random = new Random();//以42为随机数种子


    /**
     * 通过金额(分)计算折扣金额(分)
     *
     * @param price
     * @param discount
     *
     * @return double
     */
    public static int getDiscountPrice(int price, double discount) {
        BigDecimal a = new BigDecimal(Integer.toString(price));
        BigDecimal b = new BigDecimal(Double.toString(discount));
        return round(a.multiply(b).doubleValue(), INTEGER_SCALE);
    }

    /**
     * 获得加入购物车中的折扣商品价格
     *
     * @param price
     * @param discount
     * @return
     */
    public static int getItemDiscountPrice(int price, double discount){
        BigDecimal a = new BigDecimal(Integer.toString(price));
        BigDecimal b = new BigDecimal(Double.toString(discount));
        BigDecimal hundred = new BigDecimal("100");
        return a.multiply(b).divide(hundred, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).multiply(hundred).intValue();
    }

    public static int getLimitDiscountPrice(int price, double discount){
        BigDecimal a = new BigDecimal(Integer.toString(price));
        BigDecimal b = new BigDecimal(Double.toString(discount));
        BigDecimal hundred = new BigDecimal("100");
        return a.multiply(b).divide(hundred, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double getDoubleValue(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v     需要四舍五入的数字
     * @return 四舍五入后的结果
     */
    public static int round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).intValue();
    }


    /**
     * 通过金额(分)计算实际金额(元)
     * num 除以 100 ，保留2位小数
     * （注：若结果为整数，则为 xx.0 ）
     *
     * @param num
     * @return double
     */
    public static double getRealMoney(int num) {
        BigDecimal b = new BigDecimal(Integer.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return b.divide(hundred, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 通过金额(分)计算实际金额(元)
     * num 除以 100 ，保留2位小数
     * （注：若结果为整数，则为 xx.0 ）
     *
     * @param num
     * @return double
     */
    public static double getRealMoney(long num) {
        BigDecimal b = new BigDecimal(Long.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return b.divide(hundred, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 通过数量 count * 金额(元) num
     *
     * @param count
     * @param num
     * @return
     */
    public static double getRealMoney(int count,String num){
        BigDecimal b = new BigDecimal(num);
        BigDecimal c = new BigDecimal(Integer.toString(count));
        BigDecimal one = new BigDecimal("1");
        return b.multiply(c).divide(one,DEFAULT_DIV_SCALE,BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 通过金额(分)计算实际金额(元)
     * num 除以 100 ，保留2位小数，并格式化为 xx.00
     *
     * @param num
     * @return String
     */
    public static String getRealMoneyStr(int num) {
        BigDecimal b = new BigDecimal(Integer.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return new DecimalFormat(YUAN_FORMAT_PATTEN).format(b.divide(hundred, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 通过金额(分)计算实际金额(元)
     * num 除以 100 ，保留2位小数，并格式化为 xx.00
     *
     * @param num
     * @return String
     */
    public static String getRealMoneyStr(long num) {
        BigDecimal b = new BigDecimal(Long.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return new DecimalFormat(YUAN_FORMAT_PATTEN).format(b.divide(hundred, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 将金额(元)转换为字符串
     * 保留2位小数，并格式化为 xx.00
     *
     * @param num
     * @return
     */
    public static String getRealMoneyStr(double num){
        BigDecimal b = new BigDecimal(Double.toString(num));
        BigDecimal one = new BigDecimal("1");
        return new DecimalFormat(YUAN_FORMAT_PATTEN).format(b.divide(one, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
    }


    /**
     * 通过金额(分)计算实际金额(元)  (抽奖展示使用)
     * num 除以 100 ，并格式化为 xx 元
     *
     * @param num
     * @return String
     */
    public static String getRealMoneyStr4Lottery(int num) {
        BigDecimal b = new BigDecimal(Integer.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return new DecimalFormat(COUPON_FORMAT_PATTEN).format(b.divide(hundred, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 将金额(元)转换为金额(分)
     *
     * @param num
     * @return
     */
    public static int getIntegerMoney(double num){
        BigDecimal b = new BigDecimal(Double.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        BigDecimal one = new BigDecimal("1");
        return b.multiply(hundred).divide(one, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 将金额(元)转换为金额(分)
     *
     * @param num
     * @return
     */
    public static int getIntegerMoney(String num){
        BigDecimal b = new BigDecimal(num);
        BigDecimal hundred = new BigDecimal("100");
        BigDecimal one = new BigDecimal("1");
        return b.multiply(hundred).divide(one, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 将金额(元)转换为金额(分)
     *
     * @param num
     * @return
     */
    public static int getIntegerMoney(int num){
        BigDecimal b = new BigDecimal(Integer.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        BigDecimal one = new BigDecimal("1");
        return b.multiply(hundred).divide(one, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 通过金额(分)计算积分，用于返还积分计算
     * num 除以 100 ，取整
     *
     * @param num
     * @return
     */
    public static int getIntegral(int num) {
        BigDecimal b = new BigDecimal(Integer.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return b.divide(hundred, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 通过金额(分)计算金额(元)，用于计算优惠券，红包价格
     * num 除以 100 ，取整
     *
     * @param num
     * @return
     */
    public static int getIntegerPrice(int num) {
        BigDecimal b = new BigDecimal(Integer.toString(num));
        BigDecimal hundred = new BigDecimal("100");
        return b.divide(hundred, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 根据价格占比，计算分摊的积分数
     * （1积分 = 金额1分）
     *
     * @param singlePrice 单一价格
     * @param totalPrice 总价格
     * @param tempPrice 使用的金额(分)
     * @return
     */
    public static int getProportionPrice(int singlePrice, int totalPrice, int tempPrice) {
        BigDecimal single = new BigDecimal(Integer.toString(singlePrice));
        BigDecimal total = new BigDecimal(Integer.toString(totalPrice));
        BigDecimal temp = new BigDecimal(Integer.toString(tempPrice));
        BigDecimal temp2 = single.multiply(temp);
        if(temp2.intValue() == 0){
            return 0 ;
        }
        return temp2.divide(total, INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     *
     * @param price  商品丽子价,单位元
     * @param nynjPrice N元N件活动价
     * @param nynjCount N元N件个数
     * @param n      倍数
     * @param total  满足N元N件所有商品的丽子总价
     * @return
     */
    public static String getNynjMoney(String price,int nynjPrice,int n,int total,int nynjCount) {
        int money = NumberUtil.getIntegerMoney(Double.parseDouble(price)) * n;
        BigDecimal a = new BigDecimal(Integer.toString(money));
        BigDecimal b = new BigDecimal(Integer.toString(nynjPrice));
        BigDecimal c = new BigDecimal(Integer.toString(total * nynjCount));
        int value = a.multiply(b).divide(c,INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();
        return NumberUtil.getRealMoneyStr(value) ;
    }

    /**
     *
     * @param price 商品丽子价,单位分
     * @param nynjPrice
     * @param n
     * @param total
     * @param nynjCount
     * @return
     */
    public static int getIntegerNynjMoney(BigDecimal price,int nynjPrice,int n,int total,int nynjCount) {
        int money =  price != null ? price.intValue() * n :0;
        BigDecimal a = new BigDecimal(Integer.toString(money));
        BigDecimal b = new BigDecimal(Integer.toString(nynjPrice));
        BigDecimal c = new BigDecimal(Integer.toString(total * nynjCount));
        return a.multiply(b).divide(c,INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).intValue();

    }

    /**
     * 计算该订单分摊的余额
     *
     * @param singleTotalPrice    订单商品总价
     * @param allOrderPrice 多个订单的商品总价
     * @param usedCapital   使用的余额
     * @return
     */
    public static int getBalancePrice(int singleTotalPrice, int allOrderPrice, double usedCapital) {
        BigDecimal singlePrice = new BigDecimal(Integer.toString(singleTotalPrice));
        BigDecimal allPrice = new BigDecimal(Integer.toString(allOrderPrice));
        BigDecimal capital = new BigDecimal(Double.toString(usedCapital));
        BigDecimal hundred = new BigDecimal("100");
        return singlePrice.multiply(capital.multiply(hundred)).divide(allPrice,INTEGER_SCALE,BigDecimal.ROUND_HALF_UP).intValue();
    }

    /**
     * 根据实际退款金额，最多退款金额，购买商品数量，估算退货数量
     *
     * @param refundPrice
     * @param totalPrice
     * @param skuCount
     * @return
     */
    public static int getRefundCount(int refundPrice,int totalPrice,int skuCount){
        BigDecimal refund = new BigDecimal(Integer.toString(refundPrice));
        BigDecimal total = new BigDecimal(Integer.toString(totalPrice));
        BigDecimal count = new BigDecimal(Integer.toString(skuCount));
        return refund.multiply(count).divide(total,INTEGER_SCALE,BigDecimal.ROUND_UP).intValue();
    }

    /**
     * 根据毫秒数，获得秒数
     *
     * @param millis
     * @return
     */
    public static long getSecbyMillis(long millis){
        return new BigDecimal(millis).divide(new BigDecimal("1000"), INTEGER_SCALE, BigDecimal.ROUND_HALF_UP).longValue();
    }

    /**
     * 获得一定范围区间的随机数
     *
     * @param min
     * @param max
     * @return
     */
    public static int getRandomNum(int min,int max){
        return random.nextInt(max-min+1)+min;
    }

    /**
     * 获得抽奖商品概率下限
     *
     * @return
     */
    public static double getLotteryLimit(int probablity,int sum,double upLimit){
        return new BigDecimal(Integer.toString(probablity)).divide(new BigDecimal(Integer.toString(sum)),DEFAULT_DIV_SCALE,BigDecimal.ROUND_HALF_UP).add(new BigDecimal(Double.toString(upLimit))).doubleValue();
    }


    // 除以100保留两位小数
    public static String formatNumber (Object num) {
        return  minFormat.format(num);

    }

    // 把字符串转换成整形
    public static int stringToInt (String str) {
        Double d = Double.parseDouble(str);
        return (int)(d * 100);

    }

}
